package com.dynamic.mybatis.core.session;

import com.dynamic.mybatis.core.enums.CommandType;
import com.dynamic.mybatis.core.exceptions.MybatisExecutorRollbackException;
import com.dynamic.mybatis.core.metadata.DynamicConfiguration;
import com.dynamic.mybatis.core.metadata.DynamicMappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.TransactionIsolationLevel;
import org.mybatis.spring.SqlSessionHolder;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationManager;

/**
 * @Description  生成动态sql后会执行sql,验证sql是否正确
 * @Author xs
 * @Date 2021/3/24 18:02
 */
public abstract class DynamicSqlSessionPreparedStatement extends DynamicSqlSessionInterceptHandler {

    public <T> T  executeTest(DynamicMappedStatement dms){
        return  executeTest(dms,null,null);
    }

    public <T> T  executeTest(DynamicMappedStatement dms, Object parameter){
        return  executeTest(dms,parameter,null);
    }


    /**
     * @Description: 执行SQl后不会删除mappedStatement,下次直接调用execute执行
     * @param dms
     * @param parameter 参数(一般使用Map)
     * @param parameter 分页参数说明
     * pageNumber 当前页码从1开始，默认为1。 pageSize 每页数量，默认为10
     * offset 起始行下标从0开始  limit 筛选数量
     * 示例 {"pageNumber":1,"pageSize":10}或{offset:0,limit:10}
    　*/
    public  <T> T  executeTest(DynamicMappedStatement dms,Object parameter,Object dataSourceKey){
        return  executeRollback(dms,parameter,dataSourceKey);
    }

    protected    <T> T  executeRollback( DynamicMappedStatement dms, Object parameter, Object dataSourceKey){
        SqlSessionFactory  sqlSessionFactory = getSqlSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.SIMPLE, TransactionIsolationLevel.READ_UNCOMMITTED);
        //开启事务
        TransactionSynchronizationManager.bindResource(sqlSession,new  SqlSessionHolder(sqlSession,ExecutorType.SIMPLE,null));
        try {
            return getDynamicSqlSession().execute(sqlSession,dms,parameter,dataSourceKey,false);
        }finally {
            if(sqlSession != null){
                if( dms.getCommandType() != CommandType.StandardCommand.SELECT){
                    sqlSession.rollback(true);
                }else {
                    sqlSession.flushStatements();
                }
            }
            //解除事务
            TransactionSynchronizationManager.unbindResource(sqlSession);
            sqlSession.close();
        }
    }

}